using UnityEditor;
using Sirenix.OdinInspector;
using UnityEngine;
using System.IO;


namespace Life.UI.MVC.Editor
{
    [HideLabel]
    [System.Serializable]
    public class SettingsData
    {
        public string NamespaceRoot = "WorkFlow.UI";
        public string UIRootPath = "Assets/WorkFlow/UI/Scripts";
        
#if MVCUI_CUSTOM_ENABLED
        public string ProductName;
        public string UIPageTypeName = "UIPageTypes";
#endif
        
        public SettingsData()
        {
            if (File.Exists("MVC-UI/SettingsData.json"))
            {
                var stringContent = File.ReadAllText("MVC-UI/SettingsData.json");
                JsonUtility.FromJsonOverwrite(stringContent, this);
            }
        }

        [Button]
        private void Apply()
        {
            var stringContent = JsonUtility.ToJson(this);
            if (!Directory.Exists("MVC-UI"))
                Directory.CreateDirectory("MVC-UI");
            File.WriteAllText("MVC-UI/SettingsData.json", stringContent);
        }
    }

    [HideLabel]
    [System.Serializable]
    public class CreateData
    {

        [Header("请输入UI名称")] public string UIName;
        [Header("请输入UI模型名称/若无则不创建")] public string UIModelName;

        [HideInInspector] public SettingsData SettingsData;

        [Button("创建UI")]
        private void CreateUI()
        {
            if (SettingsData == null)
                return;
            if (string.IsNullOrEmpty(UIName))
            {
                EditorUtility.DisplayDialog("提示", "请输入UI名称", "确定");
                return;
            }

            if (!Directory.Exists(SettingsData.UIRootPath))
            {
                Directory.CreateDirectory(SettingsData.UIRootPath);
            }

            CreateController();
            CreateView();
            if(!string.IsNullOrEmpty(UIModelName))
                CreateModel();
            AssetDatabase.Refresh();
        }

        private void CreateController()
        {
#if !MVCUI_CUSTOM_ENABLED
            var txt = string.Format(TemplateString.ControllerTemplate, SettingsData.NamespaceRoot, UIName);
#else
            var txt = TemplateString.ControllerTemplate.Replace("{0}",SettingsData.NamespaceRoot);
            txt = txt.Replace("{1}",UIName);
            txt = txt.Replace("{2}",SettingsData.ProductName);
#endif
            string directory = Path.Combine(SettingsData.UIRootPath, "Controller");
            var path = Path.Combine(directory, $"{UIName}.cs");
            if(!Directory.Exists(directory))
                Directory.CreateDirectory(directory);
            if (File.Exists(path))
            {
                Debug.LogError($"{path} 已存在！！！");
                return;
            }
            File.WriteAllText(path, txt);
        }
        
        private void CreateView()
        {
            var txt = string.Format(TemplateString.ViewTemplate, SettingsData.NamespaceRoot, UIName,SettingsData.ProductName);
            string directory = Path.Combine(SettingsData.UIRootPath, "View");
            var path = Path.Combine(directory, $"{UIName}View.cs");
            if(!Directory.Exists(directory))
                Directory.CreateDirectory(directory);
            if (File.Exists(path))
            {
                Debug.LogError($"{path} 已存在！！！");
                return;
            }
            File.WriteAllText(path, txt);
        }

        private void CreateModel()
        {
            var txt = string.Format(TemplateString.ModelTemplate, SettingsData.NamespaceRoot, UIModelName,SettingsData.UIPageTypeName);
            string directory = Path.Combine(SettingsData.UIRootPath, "Model");
            var path = Path.Combine(directory, $"{UIModelName}Model.cs");
            if(!Directory.Exists(directory))
                Directory.CreateDirectory(directory);
            if (File.Exists(path))
            {
                Debug.LogError($"{path} 已存在！！！");
                return;
            }
            File.WriteAllText(path, txt);
        }
    }

    
#if !MVCUI_CUSTOM_ENABLED
    [HideLabel]
    [System.Serializable]
    public class TypesData
    {
        [SerializeField]
        private List<TypeItem> _Types;
        
        
        private TypeItem[] _TypesBefore;
        
        public SettingsData SettingsData{
            get;
            set;
        }
        public TypesData()
        {

            _Types = new List<TypeItem>(ControllerType.Length);
            var fields = typeof(ControllerType).GetFields();
            foreach (var field in fields)
            {
                var attribute = field.GetAttribute<TooltipAttribute>(true);
                string tips = attribute != null ? attribute.tooltip : "";
                _Types.Add(new TypeItem()
                { 
                    Tips = tips,
                    UIType = field.Name,
                    Value = (int)field.GetValue(null)
                });
            }
            _Types.Sort((x, y) => x.Value.CompareTo(y.Value));
            _TypesBefore = _Types.ToArray();

        }
        [Button]
        private void Apply()
        {
            if (SettingsData!=null && NotSame())
            {
                StringBuilder sb = new StringBuilder();
                foreach (var item in _Types)
                {
                    sb.AppendFormat(TemplateString.ControllerTypeItemTemplate, item.Tips, item.UIType, item.Value);
                }
                var txt = string.Format(TemplateString.ControllerTypeTemplate, sb.ToString());

                if (!Directory.Exists(SettingsData.UITypeFilePath))
                    Directory.CreateDirectory(SettingsData.UITypeFilePath);
                var path = Path.Combine(SettingsData.UITypeFilePath, "ControllerType.cs");
                if(File.Exists(path))
                    File.Delete(path);
                File.WriteAllText(path, txt);
                AssetDatabase.Refresh();
            }
        }

        bool NotSame()
        {
            if (_Types.Count != _TypesBefore.Length)
                return true;
            bool notSame = false;
            for(int i = 0; i < _Types.Count; i++)
            {
                if (_Types[i].UIType != _TypesBefore[i].UIType || _Types[i].Value != _TypesBefore[i].Value 
                    || _Types[i].Tips != _TypesBefore[i].Tips )
                {
                    notSame = true;
                    break;
                }
            }
            return notSame;
        }
    }
#endif
    
    [System.Serializable]
    public struct TypeItem
    {
        public string Tips;
        public string UIType;
        public int Value;
    }
   
    public static class TemplateString
    {
        #if !MVCUI_CUSTOM_ENABLED
        public static readonly string ControllerTemplate = @"using Life.UI.MVC.Model;
using Life.UI.MVC.View;
using Life.UI.MVC.Controller;
using {1}.Model;

namespace {0}.Controller
{{
    public sealed class {1} : ControllerBase
    {{
        private {1}View _currentView;
        protected override void OnAwake(bool completed)
        {{
            _currentView = ({1}View)_view;
        }}

        protected override bool OnModelUpdate(ModelBase model)
        {{
            return false;
        }}
    }}
}}
";
        #else
        public static readonly string ControllerTemplate = @"using Life.UI.MVC.Model;
using {0}.View;
using Life.UI.MVC.Controller;
using UnityEngine;

namespace {0}.Controller
{
    [AddComponentMenu(""Games/{2}/UI/Controller/{1}-{2}"")]
    public sealed class {1} : ControllerBase
    {
        [SerializeField][Header(""UI关注的ModelToken"")]
        private UIPageTypes controllerType;//使用你需要的类型作为控制器类型。

        private {1}View _currentView;

        protected override int GetControllerType()
        {
            return (int)controllerType;//在此返回你的类型转为int类型的值即可。
        }

        protected override void OnAwake(bool completed)
        {
            _currentView = ({1}View)_view;
        }

        protected override bool OnModelUpdate(ModelBase model)
        {
            return false;
        }
    }
}
";
        #endif
        
        public static readonly string ViewTemplate = @"using Life.UI.MVC.View;
using UnityEngine;

namespace {0}.View
{{
    [AddComponentMenu(""Games/{2}/UI/View/{1}-View-{2}"")]
    public sealed class {1}View : ViewBase
    {{
        public override void OnClear()
        {{
            
        }}
    }}
}}
";

        public static readonly string ModelTemplate = @"using Life.UI.MVC.Model;
namespace {0}.Model
{{
    public sealed class {1}Model : ModelBase
    {{
        public {1}Model({2} pageType) : base((int)pageType)
        {{
            // 初始化模型数据
        }}
    }}
}}
";
        public static readonly string ControllerTypeTemplate = @"using UnityEngine;
using ControllerTypeValue = System.Int32;
namespace Life.UI.MVC
{{
    public static partial class ControllerType
    {{
        {0}
    }}
}}
";

        public static readonly string ControllerTypeItemTemplate = @"
        /// <summary>
        /// {0}
        /// </summary>
        [Tooltip(""{0}"")]
        public const ControllerTypeValue {1} = {2};
";
    }
}
